<?php

namespace coreapi\controllers;

use common\constants\Constants;
use coreapi\tables\base\Guide;
use Yii;
use yii\web\Response;

/**
 *@auth jianbiao11
 *
 **/
class BaseAPIController extends MainController {
	public $enableCsrfValidation = false;
	public $clientInfo;
	public $start_time;
	public $apiHeader = [];

	public $swoole_client;

	public function beforeAction($action) {

		$this->apiLog(basename(__FILE__) . 'Line :' . __LINE__ . 'Index result : ' . json_encode($_REQUEST), $module = '');

		//处理json方式的参数请求，解析出来后存入_POST数组中
		if (\Yii::$app->request->isPost) {
			$params = json_decode(file_get_contents('php://input'), true);
			if (isset($params) || (!empty($params))) {
				$_POST = array_merge($_POST, $params);
			}
		}

		//获取请求的URL
		$route = Yii::$app->requestedRoute;
		if ($route != 'api/login' && $route != 'api/push' && $route != 'api/login/test') {
			$request = \Yii::$app->request;
			$post = $request->post();
			$uid = $request->post('uid', '00');
			$token = $request->post('token', '00');
			if ($uid == '00' || $token == '00') {
				$return = $this->getFailedArray('auth error');
				header("Content-Type:application/json; charset=UTF-8");
				echo json_encode($return, JSON_UNESCAPED_UNICODE);
				exit;
			}
			$guide = Guide::findOne($uid);
			if ($guide == null) {
				$return = $this->getFailedArray('not find user');
				header("Content-Type:application/json; charset=UTF-8");
				echo json_encode($return, JSON_UNESCAPED_UNICODE);
				exit;
			} else {
				if ($guide->token != $token) {
					$return = $this->getFailedArray('token error');
					header("Content-Type:application/json; charset=UTF-8");
					echo json_encode($return, JSON_UNESCAPED_UNICODE);
					exit;
				}
			}

		}

		$params = \Yii::$app->params;
		//判断参数是否合法
		if (array_key_exists('isCheckAccess', $params)) {
			//是否进行访问验证
			$isCheckAccess = $params['isCheckAccess'];
			if ($isCheckAccess) {
				$checkResult = $this->checkAccess();
				if ($checkResult["status"] == 0) {
					return parent::beforeAction($action);
				} else {
					header("Content-Type:application/json; charset=UTF-8");
					echo json_encode($checkResult, JSON_UNESCAPED_UNICODE);
					exit;
				}
			}
		}

		$this->swoole_client = \Yii::$app->swoole_client;
		//字模块定义文件，基于此文件可完成服务的单独部署
		$filename = \Yii::setAlias('@coreapi') . "/config/rpcserver/server.conf.json";

		//custom initialization code goes here
		if (file_exists($filename)) {
			$configJson = file_get_contents($filename);
			$serverConfig = json_decode($configJson, true);
			$this->swoole_client->initConfig($serverConfig);
		} else {
			//暂时抛出异常
			throw new Exception("modules.json not found", 1);
		}

		$this->swoole_client = $this->swoole_client->getClient();
		return parent::beforeAction($action);
	}

	/**
	 * 这里放入权限等验证
	 * @return [type] [description]
	 */
	private function checkAccess() {
		$checkResult = $this->checkIPs();
		if ($checkResult["status"] == 0) {
			//TODO:做一些参数拦截等操作
			$checkResult = $this->checkHeader();
			if ($checkResult["status"] == 0) {
				return $checkResult;
			} else {
				header("Content-Type:application/json; charset=UTF-8");
				echo json_encode($checkResult, JSON_UNESCAPED_UNICODE);
				exit;
			}
			return $checkResult;
		} else {
			header("Content-Type:application/json; charset=UTF-8");
			echo json_encode($checkResult, JSON_UNESCAPED_UNICODE);
			exit;
		}
	}

	/**
	 * check Header参数是否合法
	 * @return [type] [description]
	 */
	private function checkHeader() {
		$params = \Yii::$app->params;
		if (array_key_exists('allowedAppKeys', $params)) {
			$allowedAppKeys = $params['allowedAppKeys'];
		} else {
			return \Yii::$app->utils->getSuccessArray([], '', Constants::STATUS_SUCCESS);
		}
		$headers = Yii::$app->request->headers;
		$apiHeader = $headers;
		$appKey = $apiHeader->get("X-AppKey", "0");
		foreach ($allowedAppKeys as $filter) {
			if ($filter === '*' || $filter === $appKey || (($pos = strpos($filter, '*')) !== false && !strncmp($appKey, $filter, $pos))) {
				return \Yii::$app->utils->getSuccessArray([], '', Constants::STATUS_SUCCESS);
			}
		}
		Yii::warning('Access to coreapi is denied due to APP-KEY restriction. The requesting  APP-KEY is ' . $appKey, __METHOD__);
		return \Yii::$app->utils->getFailedArray('APP-KEY为非法授权码，访问被拒.', Constants::STATUS_FAILED, []);

	}

	/**
	 * 判断IP是否合法
	 * @return [type] [description]
	 */
	private function checkIPs() {
		$params = \Yii::$app->params;
		if (array_key_exists('allowedIPs', $params)) {
			$allowedIPs = $params['allowedIPs'];
		} else {
			$allowedIPs = ['*'];
		}

		$ip = Yii::$app->getRequest()->getUserIP();
		\Yii::info("coreapi 访问IP：" . $ip);
		foreach ($allowedIPs as $filter) {
			if ($filter === '*' || $filter === $ip || (($pos = strpos($filter, '*')) !== false && !strncmp($ip, $filter, $pos))) {
				return \Yii::$app->utils->getSuccessArray([], '', Constants::STATUS_SUCCESS);
			}
		}
		Yii::warning('Access to coreapi is denied due to IP address restriction. The requesting IP address is ' . $ip, __METHOD__);
		return \Yii::$app->utils->getFailedArray('IP($ip)为非法地址，访问被拒.', Constants::STATUS_FAILED, []);
	}

	public function afterAction($action, $result) {
		$result = parent::afterAction($action, $result);

		//var_dump($action);
		//echo json_encode($result->data);
		//echo "------------------------------------";
		$search_condition = Yii::$app->request->get();
		//var_dump(Yii::$app->request->getPathInfo());
		//var_dump(json_encode($search_condition));

		// your custom code here
		return $result;
	}

	/**
	 * @param array|string $url
	 * @param int $statusCode
	 * @return null
	 * @throws ErrorException
	 */
	public function redirect($url, $statusCode = 302) {
		throw new ErrorException("You should not use 'redirect' method,this method is not compatible with app api");
		return null;
	}

	/**
	 * 执行成功，组装应答数据
	 * @param array $data 数据
	 * @param string $msg 提示信息
	 * @param int $status 状态码
	 * @return array
	 */
	protected function getSuccessArray($data = [], $msg = '请求成功', $status = Constants::STATUS_SUCCESS) {
		return \Yii::$app->utils->getSuccessArray($data, $msg, $status);
	}

	/**
	 * 执行失败，组装应答数据
	 * @param string $msg 提示信息
	 * @param int $status 状态码
	 * @param array $data 数据
	 * @return array
	 */
	protected function getFailedArray($msg = '', $status = Constants::STATUS_FAILED, $data = []) {
		return \Yii::$app->utils->getFailedArray($msg, $status, $data);
	}

	/**
	 * 返回json数据
	 * @param $data
	 * @return \yii\console\Response|Response
	 */
	protected function returnJson($data) {
		\Yii::info("coreapi 返回结果为：" . json_encode($data, JSON_UNESCAPED_UNICODE));
		return $this->assembleAppResponse($data);
	}

	/**
	 * 返回json格式SUCESS数据
	 * @param array $data
	 * @param string $msg
	 * @param int $status
	 * @return \yii\console\Response|Response
	 */
	protected function returnSuccessJson($data = [], $msg = '请求成功', $status = Constants::STATUS_SUCCESS) {
		return $this->returnJson($this->getSuccessArray($data, $msg, $status));
	}

	/**
	 * 返回json格式FAILED数据
	 * @param string $msg
	 * @param int $status
	 * @param array $data
	 * @return \yii\console\Response|Response
	 */
	protected function returnFailedJson($msg = '', $status = Constants::STATUS_FAILED, $data = []) {
		return $this->returnJson($this->getFailedArray($msg, $status, $data));
	}

	/**
	 * 组装app端返回数据
	 * @param $params
	 * @return \yii\console\Response|Response
	 */
	private function assembleAppResponse($params) {
		\Yii::$app->response->format = Response::FORMAT_JSON;
		\Yii::$app->response->data = $params;
		return \Yii::$app->response;
	}

	/**
	 * 调试、打印变量
	 * @param mixed $res
	 */
	public function p($res) {
		if (is_string($res)) {
			echo $res . "<br />\n";
		} elseif (is_array($res)) {
			echo "<pre>\n";
			print_r($res);
			echo '</pre>\n';
		} else {
			echo "<pre>\n";
			var_dump($res);
			echo "</pre>\n";
		}
	}

}
